﻿/*****************************************************************//**
 * \file   wit.h
 * \brief  维特智能传感器的相关数据处理
 * 
 * \author CaiYunWei
 * \date   August 2024
 *********************************************************************/

#pragma once
#include <ctime>
#include <stdint.h>


/**
 * @brief 维特智能相关
 */
namespace WIT
{
	/**
	 * 数据内容.
	 */
	enum TYPE
	{
		TIME = 0x50,	//时间
		ACC = 0x51,	//加速度(和温度)
		GYRO = 0x52,	//角速度（陀螺仪数据）
		ANGLE = 0x53,	//角度（和版本号）
		MAGNETIC = 0x54,	//磁场(经实验，磁场数据包没有温度数据)
		//DPORT = 0x55,	//端口状态
		//PRESS = 0x56,	//气压高度
		//GPS = 0x57,	//经纬度
		//VELOCITY = 0x58,	//地速
		QUATER = 0x59	//四元数
		//GSA = 0x5A,//GPS定位精度
		//REGVALUE = 0x5F	//读取
	};
	

	/**
	 * @brief 处理得到的原始数据并格式化以便于.csv记录.
	 * @param pData [IN] 数据包指针
	 * @param count [IN] 数据长度（应为11倍数）
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 成功
	 * @return false 失败
	 */
	bool dataSprintf(const void* pData, const size_t count, char* buffer, size_t* strLength = nullptr);

	/**
	 * @brief 处理需要的66字节的数据
	 * @param pData [IN] 数据包指针
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 成功
	 * @return false 失败
	 */
	bool IMUdataSprintf(const void* pData, char* buffer, size_t* strLength = nullptr);

	/**
	 * @brief 处理一个数据包
	 * @param pData [IN] 数据包指针
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 一切正常
	 * @return false 发生错误
	 */
	bool packetSprintf(const void* pData, char* buffer, size_t* strLength = nullptr);

	/**
	 * @brief 得到数据包类型
	 * @param pData [IN] 数据包指针
	 * @param theType [OUT] 数据类型
	 * @return true 正常
	 * @return false 出现异常
	 */
	bool getDataType(const void* pData, TYPE* theType);

	/**
	 * @brief 得到时间.
	 * @param pData [IN] 时间数据包起始地址
	 * @param pTime [OUT] 时间数据的结构体（标准库）保存地址
	 * @param ms [OUT]毫秒的保存地址
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool getTime(const void* pData, tm* pTime = nullptr, int16_t* ms = nullptr);

	/**
	 * @brief 处理时间数据并格式化成字符串
	 * @param pData [IN] 时间数据包起始地址
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool timeSprintf(const void* pData, char* buffer, size_t* strLength = nullptr);

	/**
	 * @brief 得到加速度
	 * @param pData 加速度数据包起始地址
	 * @param Ax x方向加速度保存位置 单位 米每二次方秒
	 * @param Ay y方向加速度保存位置 单位 米每二次方秒
	 * @param Az z方向加速度保存位置 单位 米每二次方秒
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool getAcceleration(const void* pData, float* Ax, float* Ay, float* Az);

	/**
	 * @brief 处理加速度数据并格式化成字符串
	 * @param pData [IN] 加速度数据包起始地址
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool accelerationSprintf(const void* pData, char* buffer, size_t* strLength = nullptr);

	/**
	 * 得到温度.
	 *
	 * \param pData [IN] 温度数据包起始地址
	 * \param pT [OUT] 温度保存位置 单位 摄氏度
	 * \return true 校验通过
	 * \return false 校验不通过
	 */
	bool getTemperature(const void* pData, float* pT);


	/**
	 * @brief 得到角速度
	 * @param pData [IN] 角速度数据包起始地址
	 * @param Wx [OUT] x方向角速度保存位置 单位 度每秒
	 * @param Wy [OUT] y方向角速度保存位置 单位 度每秒
	 * @param Wz [OUT] z方向角速度保存位置 单位 度每秒
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool getAngularSpeed(const void* pData, float* Wx, float* Wy, float* Wz);

	/**
	 * @brief 处理角速度数据并格式化成字符串
	 * @param pData [IN] 角速度数据包起始地址
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool angularSpeedSprintf(const void* pData, char* buffer, size_t* strLength = nullptr);

	/**
	 * @brief 得到欧拉角
	 * @param pData pData [IN] 角度数据包起始地址
	 * @param Roll [OUT] 滚转⻆X保存位置 单位 度
	 * @param Pitch [OUT] 俯仰⻆Y保存位置 单位 度
	 * @param Yaw [OUT] 偏航⻆Z保存位置 单位 度
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool getAngle(const void* pData, float* Roll, float* Pitch, float* Yaw);

	/**
	 * @brief 处理欧拉角数据并格式化成字符串
	 * @param pData [IN] 欧拉角数据包起始地址
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool angleSprintf(const void* pData, char* buffer, size_t* strLength = nullptr);

	/**
	 * 得到版本号.
	 *
	 * \param pData [IN] 版本号数据包起始地址
	 * \param pVersion [OUT] 版本号保存位置
	 * \return true 校验通过
	 * \return false 校验不通过
	 */
	bool getVersion(const void* pData, uint16_t* pVersion);

	/**
	 * @brief 得到磁场.
	 * @param pData [IN] 磁场数据包起始地址
	 * @param Hx [OUT] 磁场X方向保存位置 单位 毫高斯
	 * @param Hy [OUT] 磁场Y方向保存位置 单位 毫高斯
	 * @param Hz [OUT] 磁场Z方向保存位置 单位 毫高斯
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool getMagnetic(const void* pData, int16_t* Hx, int16_t* Hy, int16_t* Hz);

	/**
	 * @brief 处理磁场数据并格式化成字符串
	 * @param pData [IN] 磁场数据包起始地址
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool magneticSprintf(const void* pData, char* buffer, size_t* strLength = nullptr);

	/**
	 * @brief 得到四元数.
	 * @param pData [IN] 四元数据包起始地址
	 * @param Q0 [OUT] Q0保存位置
	 * @param Q1 [OUT] Q1保存
	 * @param Q2 [OUT] Q2保存
	 * @param Q3 [OUT] Q3保存
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool getQuarternion(const void* pData, float* Q0, float* Q1, float* Q2, float* Q3);

	/**
	 * @brief 处理四元数数据并格式化成字符串
	 * @param pData [IN] 四元数数据包起始地址
	 * @param buffer [OUT] 保存字符串的缓冲区
	 * @param strLength [OUT] 得到的字符串的长度指针
	 * @return true 校验通过
	 * @return false 校验不通过
	 */
	bool quarternionSprintf(const void* pData, char* buffer, size_t* strLength = nullptr);
}


